/**
C++ 实例模式的几种实现方法
*/

#include <iostream>
#include <memory>
#include <mutex>

// 使用静态局部变量 static（类唯一），天生线程安全
class s1 {
   public:
    static s1& getInstance() {
        static s1 me;
        return me;
    }

    void print() { std::cout << "My address: " << this << std::endl; }

   private:
    s1();
    ~s1();
    // 禁用外部拷贝操作
    s1(const s1& single) = delete;
    // 禁用赋值操作
    const s1& operator=(const s1& single) = delete;
};

// 智能指针版本
class s2 {
   public:
    static std::shared_ptr<s2> getSingleton();

    void print() { std::cout << "Hello World." << std::endl; }

    ~s2() { std::cout << __PRETTY_FUNCTION__ << std::endl; }

   private:
    s2() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};

static std::shared_ptr<s2> singleton = nullptr;
static std::mutex singletonMutex;

std::shared_ptr<s2> s2::getSingleton() {
    if (singleton == nullptr) {
        // 加锁
        std::unique_lock<std::mutex> lock(singletonMutex);
        if (singleton == nullptr) {
            auto temp = std::shared_ptr<s2>(new s2());
            singleton = temp;
        }
    }
    return singleton;
}